﻿using System.Threading.Tasks;
using MaxStoreErp.Core.Events;
using MaxStoreErp.Core.Infrastructure;
using MaxStoreErp.Core.Interfaces;
using MaxStoreErp.Core.Services;
using MaxStoreErp.Shell.MainMenu;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.UnityExtensions;
using Microsoft.Practices.Unity;
using System.IO;
using System.Windows;

namespace MaxStoreErp.Shell
{
    internal class Bootstrapper : UnityBootstrapper
    {
        IUnityContainer _container;

        /// <summary>
        /// Заполняет каталог модулей.
        /// </summary>
        /// <returns>Возвращает новый каталог модулей</returns>
        /// <remarks>
        /// Этот метод строит каталог модулей из существующих модулей в каталоге модулей
        /// </remarks>
        protected override IModuleCatalog CreateModuleCatalog()
        {
            if (!Directory.Exists("Modules"))
                Directory.CreateDirectory("Modules");

            var moduleCatalog = new DirectoryModuleCatalog {ModulePath = @".\Modules"};
            return moduleCatalog;
        }

        /// <summary>
        /// Создает главное окно приложения
        /// </summary>
        /// <returns>Возвращает новый экземпляр главного окна</returns>
        protected override DependencyObject CreateShell()
        {
            RegisterBaseServices();
            var wnd = _container.Resolve<MetroShell.MetroShellPresenter>();
            _container.RegisterInstance(typeof (IShellWindow), wnd);
            wnd.LoadDataAsync();
            return wnd.View;
        }

        /// <summary>
        /// Отображает главное окно пользователю
        /// </summary>
        protected override void InitializeShell()
        {
            base.InitializeShell();
            Application.Current.MainWindow = (Window) Shell;
            Application.Current.MainWindow.Show();
        }

        void RegisterBaseServices()
        {
            _container = Container;
            _container.RegisterInstance<ILogger>(new NLogLogger());
            _container.RegisterInstance(new ShellGlobalCommands());
            _container.RegisterInstance<IMainMenuService>(new MainMenuService());
            _container.RegisterInstance<IDocumentManager>(_container.Resolve<DocumentManager<MainMenuPresenter>>());
            _container.RegisterType<IMessager, MetroDialogMessage>();
            _container.RegisterType<IProgressDialog, MetroProgressDialog>();
        }

        protected override async void InitializeModules()
        {
            await Task.Factory.StartNew(() =>
            {
                base.InitializeModules();
                _container.Resolve<IEventAggregator>().GetEvent<ModuleLoadedEvent>().Publish(ModuleCatalog.Modules);
            });
        }
    }
}
